#define _CRT_SECURE_NO_WARNINGS
// #include <exception>
// #include <iostream>
// using namespace std;
// double Divide(int a, int b) {
//     if(b == 0) {
//         throw"除零异常!";
//     } else {
//         return (double)a / (double)b;
//     }
// }
// void func() {
//     int* array1 = new int[10];
//     int* array2 = new int[10];
//     try {
//         int len, time;
//         cin >> len >> time;
//         cout << Divide(len, time) << endl;
//     }catch(...) {
//         cout << "delete[]" << array1 << endl;
//         delete[] array1;
//         cout << "delete[]" << array2 << endl;
//         delete[] array2;
//     }
//     cout << "delete[]" << array1 << endl;
//     delete[] array1;
//     cout << "delete[]" << array2 << endl;
//     delete[] array2;
// }
// int main() {
//     try {
//         func();
//     } catch(exception& e) {
//         cout << e.what() << endl;
//     } catch(...) {
//         cout << "未知异常" << endl;
//     }
//     return 0;
// }

// #include <cstddef>
// #include <exception>
// #include <iostream>
// using namespace std;
// template <class T>
// class SmartPtr {
//     public:
//         SmartPtr(T* ptr) : _ptr(ptr) {}
//         ~SmartPtr() {
//             cout << "delete[]: " << _ptr << endl;
//             delete[] _ptr;
//         }
//         // 这里我们重载一些指针相关的运算符，方便我们访问资源
//         T& operator*() {
//             return *_ptr;
//         }
//         T* operator->() {
//             return _ptr;
//         }
//         T& operator[](size_t i) {
//             return _ptr[i];
//         }
//     private:
//         T* _ptr;
// };
// double Divide(int a, int b) {
//     if(b == 0) {
//         throw "除零异常!";
//     }else {
//         return (double)a / (double)b;
//     }
// }
// void Func() {
//     SmartPtr<int> sp1 = new int[10];
//     SmartPtr<int> sp2 = new int[10];

//     for(size_t i = 0; i < 10; i++) {
//         sp1[i] = sp2[i] = i;
//     }

//     int len, time;
//     cin >> len >> time;
//     cout << Divide(len, time) << endl;
// }
// int main() {
//     try {
//         Func();
//     } catch (const exception& e) {
//         cout << e.what() << endl;
//     } catch (...) {
//         cout << "未知异常" << endl;
//     }
//     return 0;
// }

// #include <cstddef>
// #include <exception>
// #include <iostream>
// #include <memory>
// using namespace std;
// template <class T>
// class SmartPtr {
//     public:
//         SmartPtr(T* ptr) : _ptr(ptr) {}
//         ~SmartPtr() {
//             cout << "delete[]: " << _ptr << endl;
//             delete[] _ptr;
//         }
//         // 这里我们重载一些指针相关的运算符，方便我们访问资源
//         T& operator*() {
//             return *_ptr;
//         }
//         T* operator->() {
//             return _ptr;
//         }
//         T& operator[](size_t i) {
//             return _ptr[i];
//         }
//     private:
//         T* _ptr;
// };

// int main() {
//     auto_ptr<int> sp1(new int(1));
//     auto_ptr<int> sp2(sp1);
//     *sp2 = 2;
//     *sp1 = 2; // 错误
//     return 0;
// }

// int main() {
//     // 拷贝构造
//     SmartPtr<int> sp1(new int[10]);
//     SmartPtr<int> sp2(sp1);

//     // 拷贝赋值
//     SmartPtr<int> sp3(new int[10]);
//     SmartPtr<int> sp4(new int[10]);
//     sp3 = sp4;
//     return 0;
// }
#include <cstddef>
#include <iostream>
#include <memory>
#include <mutex>
using namespace std;
// namespace xywl {
//     template <class T>
//     class myauto_ptr {
//         public:
//             myauto_ptr(T* ptr = nullptr) : _ptr(ptr){}
//             ~myauto_ptr() {
//                 cout << "delete: " << _ptr << endl;
//                 delete _ptr;
//             }
//             myauto_ptr(auto_ptr<T>& ap) : _ptr(ap._ptr) {
//                 ap._ptr = nullptr; // 这里是将传入的对象的资源置空，防止多次析构
//             }
//             myauto_ptr& operator=(myauto_ptr<T>& ap) {
//                 if(this != &ap) {
//                     delete _ptr; // 首先要释放原来的资源
//                     _ptr = ap._ptr; // 接管传入对象的资源
//                     ap._ptr = nullptr; // 将传入对象的指针置空
//                 }
//                 return *this;
//             }
//             T& operator*() {
//                 return *_ptr;
//             }
//             T* operator->() {
//                 return _ptr;
//             }
//         private:
//             T* _ptr;
//     };

//     template <class T>
//     class myunique_ptr {
//         public:
//             myunique_ptr(T* ptr = nullptr) : _ptr(ptr) {}
//             ~myunique_ptr() {
//                 cout << "delete: " << _ptr << endl;
//                 delete _ptr;
//             }
//             myunique_ptr(const myunique_ptr<T>& up) = delete;
//             myunique_ptr<T>& operator=(const myunique_ptr<T>& up) = delete;
//             myunique_ptr(unique_ptr<T&&> up) : _ptr(up._ptr) {
//                 up._ptr = nullptr;
//             }
//             myunique_ptr<T>& operator=(myunique_ptr<T>& up) {
//                 delete _ptr;
//                 _ptr = up._ptr;
//                 up._ptr = nullptr;
//             }
//             T& operator*() {
//                 return *_ptr;
//             }
//             T* operator->() {
//                 return _ptr;
//             }
//         private:
//             T* _ptr;
//     };
//     // template <class T>
//     // class myshared_ptr {
//     //     public:
//     //         myshared_ptr(T* ptr = nullptr) : _ptr(ptr), _count(new int(1)) {}
//     //         ~myshared_ptr() {
//     //             if(--(*_count) == 0) {
//     //                 cout << "delete: " << _ptr << endl;
//     //                 delete _ptr;
//     //                 delete _count;
//     //             }
//     //         }
//     //         myshared_ptr(myshared_ptr<T>& sp) 
//     //         :_count(sp._count)
//     //         ,_ptr(sp._ptr){
//     //             (*(_count)) ++;
//     //         } 
//     //         myshared_ptr<T>& operator=(myshared_ptr<T>& sp) {
//     //             if(_ptr != sp._ptr) {
//     //                 if(--(*_count) == 0) {
//     //                     cout << "delete: " << _ptr << endl;
//     //                     delete _ptr;
//     //                     delete _count;
//     //                 }
//     //                 _ptr = sp._ptr;
//     //                 _count = sp._count;
//     //                 *(_count)++;
//     //             }
//     //             return *this;
//     //         }
//     //         int use_count() {
//     //             return *_count;
//     //         }
//     //         T& operator*() {
//     //             return *_ptr;
//     //         }
//     //         T* operator->() {
//     //             return _ptr;
//     //         }
//     //     private:
//     //     int* _count;
//     //     T* _ptr;
//     // };
//     template <class T>
//     class myshared_ptr {
//     public:
//         myshared_ptr(T* ptr = nullptr) : _ptr(ptr), _count(new int(1)) {}
//         ~myshared_ptr() {
//             if (--(*_count) == 0) {
//                 Release();
//             }
//         }
//         myshared_ptr(myshared_ptr<T>& sp)
//             :_count(sp._count)
//             , _ptr(sp._ptr) 
//             , _mut(sp._mut){
//             Add();
//         }
//         myshared_ptr<T>& operator=(myshared_ptr<T>& sp) {
//             if (_ptr != sp._ptr) {
//                 Release();
//                 _ptr = sp._ptr;
//                 _count = sp._count;
//                 Add();
//             }
//             return *this;
//         }
//         int use_count() {
//             return *_count;
//         }
//         T& operator*() {
//             return *_ptr;
//         }
//         T* operator->() {
//             return _ptr;
//         }
//     private:
//         void Add() {
//             _mut->lock();
//             (*_count)++;
//             _mut->unlock();
//         }
//         void Release() {
//             _mut->lock();
//             bool flag = false;
//             if(--(*_count) == 0) {
//                 delete _ptr;
//                 delete _count;
//                 flag = true;
//             }
//             _mut->unlock();
//             if(flag) {
//                 delete _mut;
//             }
//         }
//     private:
//         int* _count;
//         T* _ptr;
//         mutex* _mut;
//     };
// }


// #include <algorithm>
// #include <iostream>
// #include <memory>
// using namespace std;
// int main() {
//     shared_ptr<int> sp1(new int(1));
//     shared_ptr<int> sp2(sp1);

//     *sp1 = 2;
//     *sp2 = 3;

//     cout << *sp1 << " " << *sp2 << endl;
//     cout << "count: " << sp1.use_count() << endl;

//     shared_ptr<int> sp3(new int(1));
//     shared_ptr<int> sp4(new int(2));
//     sp3 = sp4;
//     cout << *sp3 << " " << *sp4 << endl;
//     cout << "count: " << sp3.use_count() << endl;
//     return 0;
// }

// #include <iostream>
// using namespace std;
// struct ListNode {
//     int _data;
//     ListNode* _next;
//     ListNode* _prev;
//     ~ListNode() {
//         cout << "~ListNode" << endl;
//     }
// };
// int main() {
//     ListNode* node1 = new ListNode;
//     ListNode* node2 = new ListNode;
//     node1->_next = node2;
//     node2->_prev = node1;
//     delete node1;
//     delete node2;
//     return 0;
// }
// #include <iostream>
// #include <memory>
// using namespace std;
// namespace xywl {
//     template <class T>
//     class myweak_ptr {
//         public:
//             myweak_ptr() {}
//             myweak_ptr(const shared_ptr<T>& sp) : _ptr(sp.get()) {}
//             myweak_ptr<T>& operator=(const shared_ptr<T>& sp) {
//                 _ptr = sp.get();
//                 return *this;
//             }
//         private:
//             T* _ptr = nullptr;
//     };
// }


// struct ListNode {
//     int _data;
//     xywl::myweak_ptr<ListNode> _next; // 这里改成weak_ptr
//     xywl::myweak_ptr<ListNode> _prev; // 这里也改成weak_ptr
//     ~ListNode() {
//         cout << "~ListNode" << endl;
//     }
// };
// int main() {
//     shared_ptr<ListNode> node1(new ListNode);
//     shared_ptr<ListNode> node2(new ListNode);
//     cout << "node1_count: " << node1.use_count() << endl;
//     cout << "node2_count: " << node2.use_count() << endl;
//     node1->_next = node2;
//     node2->_prev = node1;
//     cout << "node1_count: " << node1.use_count() << endl;
//     cout << "node2_count: " << node2.use_count() << endl;
//     return 0;
// }

// #include <algorithm>
// #include <iostream>
// #include <memory>
// #include <string>
// using namespace std;

// int main() {
//     shared_ptr<string> sp1(new string("hello"));
//     shared_ptr<string> sp2(sp1);
//     weak_ptr<string> wp = sp1;
//     cout << wp.expired() << endl;
//     cout << wp.use_count() << endl;
//     cout << "******************" << endl;
//     // 这里sp1和sp2都指向了其他的资源，也就表示我们的weak_ptr过期了
//     sp1 = make_shared<string>("world");
//     cout << wp.expired() << endl;
//     cout << wp.use_count() << endl;
//     cout << "******************" << endl;
//     sp2 = make_shared<string>("!");
//     cout << wp.expired() << endl;
//     cout << wp.use_count() << endl;
//     cout << "******************" << endl;
//     wp = sp1;
//     cout << wp.use_count() << endl;
//     auto sp3 = wp.lock();
//     cout << wp.expired() << endl;
//     cout << wp.use_count() << endl;
//     *sp3 += "xywl";
//     cout << *sp1 << endl;
//     cout << *sp2 << endl;
//     cout << "******************" << endl;
//     return 0;
// }
// #include <thread>
// #include <mutex>
// struct AA {
//     int _a1 = 0;
//     int _a2 = 0;
//     ~AA() {
//         cout << "~AA()" << endl;
//     }
// };

// int main() {
//     shared_ptr<AA> p(new AA);
//     const size_t N = 100000;
//     mutex mtx;
//     auto func = [&]() {
//         for(int i = 0; i < N; i++) {
//             shared_ptr<AA> copy(p);  
//         }
//     };
//     thread t1(func);
//     thread t2(func);

//     t1.join();
//     t2.join();

//     cout << p.use_count() << endl;
//     return 0;
// }
// #include <iostream>
// #include <cstdio>
// using namespace std;
// struct Date {
//     int _year;
//     int _month;
//     int _day;
//     Date(int year = 1, int month = 1, int day = 1) 
//     :_year(year)
//     ,_month(month)
//     ,_day(day) {}
//     ~Date() {
//         cout << "~Date()" << endl;
//     }
// };
// template<class T>
// void DeleteArrayFunc(T* ptr)
// {
//     delete[] ptr;
// }

// template<class T>
// class DeleteArray
// {
// public:
//     void operator()(T* ptr) const
//     {
//         delete[] ptr;
//     }
// };

// class Fclose
// {
// public:
//     void operator()(FILE* ptr) const
//     {
//         std::cout << "Fclose:" << ptr << std::endl;
//         if (ptr != nullptr) {
//             fclose(ptr);
//         }
//     }
// };


// int main() {
//     // ----------------------------------------------------
//     // 1. 函数对象 (Functor) 作为删除器,仿函数
//     // ----------------------------------------------------
//     std::unique_ptr<Date, DeleteArray<Date>> up2(new Date[5], DeleteArray<Date>());
//     std::shared_ptr<Date> sp2(new Date[5], DeleteArray<Date>());

//     // ----------------------------------------------------
//     // 2. 函数指针 (Function Pointer) 作为删除器
//     // ----------------------------------------------------
//     std::unique_ptr<Date, void(*)(Date*)> up3(new Date[5], DeleteArrayFunc<Date>);
//     std::shared_ptr<Date> sp3(new Date[5], DeleteArrayFunc<Date>);

//     // ----------------------------------------------------
//     // 3. Lambda 表达式 作为删除器
//     // ----------------------------------------------------
//     auto delArrOBJ = [](Date* ptr) { 
//         delete[] ptr; 
//     };

//     std::unique_ptr<Date, decltype(delArrOBJ)> up4(new Date[5], delArrOBJ);
//     std::shared_ptr<Date> sp4(new Date[5], delArrOBJ);

//     // ----------------------------------------------------
//     // 4. 实现其他资源管理的删除器
//     // ----------------------------------------------------
//     FILE* file_a = fopen("Test.cpp", "r");
//     if (file_a) {
//         std::shared_ptr<FILE> sp5(file_a, Fclose());
//     }

//     FILE* file_b = fopen("Test.cpp", "r");
//     if (file_b) {
//         std::shared_ptr<FILE> sp6(file_b, [](FILE* ptr) {
//             std::cout << "fclose: " << ptr << std::endl;
//             if (ptr) fclose(ptr);
//         });
//     }

//     return 0;
// }

// int main() {
//     // unique_ptr<Date> up1(new Date[10]);
//     // shared_ptr<Date> sp1(new Date[10]);
//     unique_ptr<Date[]> up1(new Date[10]);
//     shared_ptr<Date[]> sp1(new Date[10]);
//     return 0;
// }



namespace xywl {

// 默认的删除器 (Default Deleter)
template<class T>
struct DefaultDelete {
    void operator()(T* ptr) const {
        // 默认使用 delete 释放单个对象
        delete ptr;
    }
};

template<class T, class D = DefaultDelete<T>>
class shared_ptr {
private:
    // 释放资源和引用计数的原子操作
    void ReleaseRef() {
        // 使用 fetch_sub(1) 实现原子递减，并获取递减前的旧值
        // 如果旧值是 1，说明递减后新值是 0，这是最后一个引用
        if (_pcount->fetch_sub(1) == 1) {
            
            // 资源释放
            if (_ptr != nullptr) {
                std::cout << "delete: " << _ptr << std::endl;
                
                // 使用自定义删除器释放资源
                _del(_ptr); 
                _ptr = nullptr;
            }
            
            // 释放控制块（引用计数器）
            delete _pcount;
            _pcount = nullptr;
        }
    }

public:
    // 构造函数
    // 注意：不再需要分配 mutex
    shared_ptr(T* ptr, D del = D())
        : _ptr(ptr),
          // 使用 std::atomic<int> 初始化，初始计数为 1
          _pcount(ptr ? new std::atomic<int>(1) : new std::atomic<int>(0)),
          _del(del)
    {
        // 构造完成后，引用计数是线程安全的
    }
    
    // 析构函数
    ~shared_ptr() {
        ReleaseRef();
    }
    
    // 拷贝构造函数
    shared_ptr(const shared_ptr& sp)
        : _ptr(sp._ptr),
          _pcount(sp._pcount),
          _del(sp._del) // shared_ptr 拷贝删除器对象
    {
        if (_ptr) {
            // 原子递增引用计数
            _pcount->fetch_add(1);
        }
    }

    // (为简洁起见，省略赋值运算符和访问运算符，它们会使用相同的原子操作)

private:
    T* _ptr;                        // 管理的资源
    std::atomic<int>* _pcount;      // 管理资源的引用计数 (原子操作)
    D _del;                         // 管理资源的删除器
};

}